package com.jplus.plugins.rpc.impl.handler.http;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.jplus.framework.mvc.ActionHandle;
import com.jplus.framework.mvc.DispatcherServlet;
import com.jplus.framework.mvc.action.Handler;
import com.jplus.framework.mvc.action.Requester;
import com.jplus.framework.util.FormatUtil;
import com.jplus.framework.util.HttpClientUtil;
import com.jplus.plugins.rpc.bean.RpcRequest;
import com.jplus.plugins.rpc.bean.RpcResponse;
import com.jplus.plugins.rpc.bean.Service;
import com.jplus.plugins.rpc.bean.ZNode;
import com.jplus.plugins.rpc.impl.handler.ServiceType;
import com.jplus.plugins.rpc.impl.iface.IAgreement;
import com.jplus.plugins.rpc.impl.iface.IWatcher;

/**
 * 
 * @author Yuanqy
 *
 */
public class HttpService implements IAgreement {

	private final Logger logger = LoggerFactory.getLogger(HttpService.class);
	public static AtomicInteger ai = new AtomicInteger(0);

	@Override
	public void opServer(IWatcher watcher, Map<String, Service> handler) throws Exception {
		if (DispatcherServlet.isWeb) {
			for (Entry<String, Service> en : handler.entrySet()) {
				Service ser = en.getValue();
				if (ser.getRpcProvider().serviceType() == ServiceType.Http) {
					Method[] ms = ser.getIface().getDeclaredMethods();
					for (Method m : ms) {
						// 接口方法不允许重载
						String ap = "/" + ser.getIface().getSimpleName() + "/" + m.getName();
						Requester req = new Requester("POST", ap);
						Handler hand = new Handler(ser.getImpl(), m, ap);
						ActionHandle.addActionMap(req, hand);// 包装成Action
					}
				}
			}
			ai.addAndGet(1);
		} else {
			logger.error("#####\tRPC[http] is error,Because the current environment is not in the web container");
			// 既然发布不成功，就将 当前类型删除
			Iterator<Entry<String, Service>> it = handler.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, Service> entry = it.next();
				if (entry.getValue().getRpcProvider().serviceType() == ServiceType.Http) {
					logger.warn("#####\t[remove]:{}", FormatUtil.toJSONString(entry.getValue()));
					it.remove();
				}
			}
		}
		watcher.process(true);// 发布完成
	}

	@Override
	public RpcResponse opClient(RpcRequest request, ZNode zn) throws Exception {
		String iface = zn.getIfaceName().substring(zn.getIfaceName().lastIndexOf(".") + 1);
		String postUrl = FormatUtil.formatParams("http://{}:{}/{}/{}/{}",
				new Object[] { zn.getHost(), zn.getPort(), zn.getAppName(), iface, request.getMethodName() });
		logger.info("send rpc post:[http]:{}", postUrl);
		String result = HttpClientUtil.sendPost(postUrl, FormatUtil.toJSONString(request.getParameters()));
		RpcResponse rps = new RpcResponse();
		Method m = request.getIface().getMethod(request.getMethodName(), request.getParameterTypes());
		rps.setRequestId(request.getRequestId());
		rps.setResult(JSON.parseObject(result, m.getReturnType()));
		return rps;
	}
}
